package git_cmd

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"os/exec"
	"regexp"
	"strings"

	"atomgit.com/openlinksaas/gitwrap/utils"
	"github.com/spf13/cobra"
)

var cloneFlagAuthType string
var cloneFlagUser string
var cloneFlagPassword string
var cloneFlagSshKey string

var _CloneGit = &cobra.Command{
	Use: "clone",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 1 {
			utils.OutputError(fmt.Errorf("need param [remote url]"))
			return
		}

		gitUrl := args[0]

		cmdPath, err := exec.LookPath("git")
		if err != nil {
			utils.OutputError(err)
			return
		}
		var gitCmd *exec.Cmd
		if cloneFlagAuthType == string(AUTH_TYPE_NONE) {
			gitCmd = exec.Command(cmdPath, "clone", "--progress", "--", gitUrl, gitFlagLocalPath)
		} else if cloneFlagAuthType == string(AUTH_TYPE_SSH_KEY) {
			gitCmd = exec.Command(cmdPath, "clone", "--progress", "--", gitUrl, gitFlagLocalPath)

			gitCmd.Env = []string{}
			gitCmd.Env = append(gitCmd.Env, os.Environ()...)
			gitCmd.Env = append(gitCmd.Env, fmt.Sprintf("GIT_SSH_COMMAND=ssh -i \"%s\"", cloneFlagSshKey))
		} else if cloneFlagAuthType == string(AUTH_TYPE_PASSWORD) {
			gitCmd = exec.Command(cmdPath, "clone", "--progress",
				"-c", utils.Quote(fmt.Sprintf("user.name=%s", cloneFlagUser)),
				"-c", utils.Quote(fmt.Sprintf("user.password=%s", cloneFlagPassword)),
				"--", gitUrl, gitFlagLocalPath)
		}
		if gitCmd == nil {
			utils.OutputError(fmt.Errorf("wrong authType"))
			return
		}
		gitCmd.Env = append(gitCmd.Env, "GIT_CLONE_PROTECTION_ACTIVE=false")
		logReader, err := gitCmd.StderrPipe()
		if err != nil {
			utils.OutputError(err)
			return
		}
		go processCloneLog(logReader)
		err = gitCmd.Start()
		if err != nil {
			utils.OutputError(err)
			return
		}
		err = gitCmd.Wait()
		if err != nil {
			utils.OutputError(err)
			return
		}
	},
}

func processCloneLog(log io.Reader) {
	re, err := regexp.Compile(`^([^:]*):.*\((\d+)/(\d+)\).*$`)
	if err != nil {
		return
	}
	reader := bufio.NewReader(log)
	for {
		line, err := reader.ReadString(byte('\r'))
		if err != nil {
			break
		}
		parts := re.FindAllStringSubmatch(line, -1)
		for _, part := range parts {
			newLine := strings.Join([]string{part[1], part[2], part[3]}, "\t")
			os.Stdout.WriteString(newLine)
			os.Stdout.WriteString("\r\n")
			os.Stdout.Sync()
		}
	}
}

func init() {
	_CloneGit.Flags().StringVar(&cloneFlagAuthType, "authType", "none", "set git clone auth type.values are none,sshKey,password")
	_CloneGit.Flags().StringVar(&cloneFlagUser, "user", "", "set git clone user")
	_CloneGit.Flags().StringVar(&cloneFlagPassword, "password", "", "set git clone password")
	_CloneGit.Flags().StringVar(&cloneFlagSshKey, "sshKey", "", "set git clone ssh key")
}
